#define EVALUATE_BINARY_OP(OP, X, Y) (*(X) OP *(Y))
#define EVALUATE_UNARY_OP(OP, R, X) (*(R) = OP *(X))

#define EVALUATE_BINARY_NUMERIC_OP_STACK(OP) switch (vm_top()->type) { \
	case ByteType:		EVALUATE_BINARY_OP(OP, &val_to_byte(vm_top()), &val_to_byte(vm_second())); break; \
	case IntType:		EVALUATE_BINARY_OP(OP, &val_to_int(vm_top()), &val_to_int(vm_second())); break; \
	case FloatType:		EVALUATE_BINARY_OP(OP, &val_to_float(vm_top()), &val_to_float(vm_second())); break; \
	case DoubleType:	EVALUATE_BINARY_OP(OP, &val_to_double(vm_top()), &val_to_double(vm_second())); break; \
	default: TYPE_ERROR(); break; }

#define EVALUATE_COMPARISON_OP_STACK(OP) switch (vm_top()->type) { \
	case ByteType:		vm_push_int(EVALUATE_BINARY_OP(OP, &val_to_byte(vm_top()), &val_to_byte(vm_second()))); break; \
	case IntType:		vm_push_int(EVALUATE_BINARY_OP(OP, &val_to_int(vm_top()), &val_to_int(vm_second()))); break; \
	case FloatType:		vm_push_int(EVALUATE_BINARY_OP(OP, &val_to_float(vm_top()), &val_to_float(vm_second()))); break; \
	case DoubleType:	vm_push_int(EVALUATE_BINARY_OP(OP, &val_to_double(vm_top()), &val_to_double(vm_second()))); break; \
	default: TYPE_ERROR(); break; }

#define EVALUATE_BINARY_INTEGER_OP_STACK(OP) switch (vm_top()->type) { \
	case ByteType:		EVALUATE_BINARY_OP(OP, &val_to_byte(vm_top()), &val_to_byte(vm_second())); break; \
	case IntType:		EVALUATE_BINARY_OP(OP, &val_to_int(vm_top()), &val_to_int(vm_second())); break; \
	default:			TYPE_ERROR(); break; }

#define EVALUATE_UNARY_INTEGER_OP_STACK(OP) switch (vm_top()->type) { \
	case ByteType:		EVALUATE_UNARY_OP(OP, &val_to_byte(vm_top()), &val_to_byte(vm_top())); break; \
	case IntType:		EVALUATE_UNARY_OP(OP, &val_to_int(vm_top()), &val_to_int(vm_top())); break; \
	default:			TYPE_ERROR(); break; }


